Analyze Result¶
In this example, you learn to use ResultAnalyzer
. You has already
use it in preivous example to instanciate plotting:
agg = hd.ResultAnalyzer(study, result)
Let’s begin by build little study with two nodes (A and B) both has a sinus-like load from 1500 to 500. Node A has a constant nuclear plan, node B has eolien with linear random.
import hadar as hd
import numpy as np
import pandas as pd
t = np.linspace(0, np.pi * 14, 168)
load = 1000 + np.sin(t) * 500
eolien = np.random.rand(t.size) * 1000
study = hd.Study(horizon=t.size, nb_scn=1)\
.network()\
.node('a')\
.consumption(name='load', cost=10 ** 6, quantity=load)\
.production(name='nuclear', cost=100, quantity=1500)\
.node('b')\
.consumption(name='load', cost=10 ** 6, quantity=load)\
.production(name='eolien', cost=50, quantity=eolien)\
.link(src='a', dest='b', cost=5, quantity=2000)\
.link(src='b', dest='a', cost=5, quantity=2000)\
.build()
opt = hd.LPOptimizer()
res = opt.solve(study)
agg = hd.ResultAnalyzer(study=study, result=res)
Low API¶
Analyzer provide a low api, that means result could not be ready-to-use, but it’s a very flexible way to analyze data. Low API enable to thinks: - set order. data has for level : node, element, scn and time. Low API can organize for your these level - filtering: for each level you can apply a filter, to only select node ‘a’, or time from 10 to 35 timestep
For examples you want select consumption named load other all node just for 57 to 78 timestep
agg.network().scn(0).consumption('load').node().time(slice(57, 78))
asked | cost | given | ||
---|---|---|---|---|
node | t | |||
a | 57.0 | 1320.592505 | 1000000.0 | 1320.592505 |
58.0 | 1209.650140 | 1000000.0 | 1209.650140 | |
59.0 | 1084.249841 | 1000000.0 | 1084.249841 | |
60.0 | 953.039486 | 1000000.0 | 953.039486 | |
61.0 | 825.067633 | 1000000.0 | 825.067633 | |
62.0 | 709.159500 | 1000000.0 | 709.159500 | |
63.0 | 613.308369 | 1000000.0 | 613.308369 | |
64.0 | 544.124344 | 1000000.0 | 544.124344 | |
65.0 | 506.378508 | 1000000.0 | 506.378508 | |
66.0 | 502.673897 | 1000000.0 | 502.673897 | |
67.0 | 533.265990 | 1000000.0 | 533.265990 | |
68.0 | 596.045087 | 1000000.0 | 596.045087 | |
69.0 | 686.681805 | 1000000.0 | 686.681805 | |
70.0 | 798.925635 | 1000000.0 | 798.925635 | |
71.0 | 925.035996 | 1000000.0 | 925.035996 | |
72.0 | 1056.316041 | 1000000.0 | 1056.316041 | |
73.0 | 1183.712406 | 1000000.0 | 1183.712406 | |
74.0 | 1298.439560 | 1000000.0 | 1298.439560 | |
75.0 | 1392.585665 | 1000000.0 | 1392.585665 | |
76.0 | 1459.658198 | 1000000.0 | 1459.658198 | |
77.0 | 1495.031689 | 1000000.0 | 1495.031689 | |
b | 57.0 | 1320.592505 | 1000000.0 | 790.231774 |
58.0 | 1209.650140 | 1000000.0 | 351.005132 | |
59.0 | 1084.249841 | 1000000.0 | 485.779325 | |
60.0 | 953.039486 | 1000000.0 | 953.039486 | |
61.0 | 825.067633 | 1000000.0 | 825.067633 | |
62.0 | 709.159500 | 1000000.0 | 709.159500 | |
63.0 | 613.308369 | 1000000.0 | 613.308369 | |
64.0 | 544.124344 | 1000000.0 | 544.124344 | |
65.0 | 506.378508 | 1000000.0 | 506.378508 | |
66.0 | 502.673897 | 1000000.0 | 502.673897 | |
67.0 | 533.265990 | 1000000.0 | 533.265990 | |
68.0 | 596.045087 | 1000000.0 | 596.045087 | |
69.0 | 686.681805 | 1000000.0 | 686.681805 | |
70.0 | 798.925635 | 1000000.0 | 798.925635 | |
71.0 | 925.035996 | 1000000.0 | 925.035996 | |
72.0 | 1056.316041 | 1000000.0 | 933.836811 | |
73.0 | 1183.712406 | 1000000.0 | 1033.211070 | |
74.0 | 1298.439560 | 1000000.0 | 601.396040 | |
75.0 | 1392.585665 | 1000000.0 | 832.053023 | |
76.0 | 1459.658198 | 1000000.0 | 439.140553 | |
77.0 | 1495.031689 | 1000000.0 | 451.215115 |
TIP If filter return only one element, set it at first. First indexes with one element are removed to avoir useless indexes.
Another example: Analyze all production first 24 timestep
agg.network().scn(0).node().production().time(slice(0,24))
avail | cost | used | |||
---|---|---|---|---|---|
node | name | t | |||
a | nuclear | 0.0 | 1500.000000 | 100.0 | 1500.000000 |
1.0 | 1500.000000 | 100.0 | 1500.000000 | ||
2.0 | 1500.000000 | 100.0 | 1500.000000 | ||
3.0 | 1500.000000 | 100.0 | 1500.000000 | ||
4.0 | 1500.000000 | 100.0 | 1500.000000 | ||
5.0 | 1500.000000 | 100.0 | 1500.000000 | ||
6.0 | 1500.000000 | 100.0 | 1500.000000 | ||
7.0 | 1500.000000 | 100.0 | 1500.000000 | ||
8.0 | 1500.000000 | 100.0 | 1500.000000 | ||
9.0 | 1500.000000 | 100.0 | 1500.000000 | ||
10.0 | 1500.000000 | 100.0 | 1500.000000 | ||
11.0 | 1500.000000 | 100.0 | 1500.000000 | ||
12.0 | 1500.000000 | 100.0 | 1388.655756 | ||
13.0 | 1500.000000 | 100.0 | 1376.698459 | ||
14.0 | 1500.000000 | 100.0 | 1157.759171 | ||
15.0 | 1500.000000 | 100.0 | 318.599505 | ||
16.0 | 1500.000000 | 100.0 | 775.000819 | ||
17.0 | 1500.000000 | 100.0 | 937.348977 | ||
18.0 | 1500.000000 | 100.0 | 32.439151 | ||
19.0 | 1500.000000 | 100.0 | 202.087813 | ||
20.0 | 1500.000000 | 100.0 | 806.885534 | ||
21.0 | 1500.000000 | 100.0 | 996.520417 | ||
22.0 | 1500.000000 | 100.0 | 1264.946884 | ||
23.0 | 1500.000000 | 100.0 | 1357.308648 | ||
b | eolien | 0.0 | 313.568200 | 50.0 | 313.568200 |
1.0 | 212.562928 | 50.0 | 212.562928 | ||
2.0 | 761.045464 | 50.0 | 761.045464 | ||
3.0 | 927.244388 | 50.0 | 927.244388 | ||
4.0 | 529.827565 | 50.0 | 529.827565 | ||
5.0 | 839.655655 | 50.0 | 839.655655 | ||
6.0 | 103.955853 | 50.0 | 103.955853 | ||
7.0 | 91.087054 | 50.0 | 91.087054 | ||
8.0 | 171.107957 | 50.0 | 171.107957 | ||
9.0 | 810.780478 | 50.0 | 810.780478 | ||
10.0 | 409.857521 | 50.0 | 409.857521 | ||
11.0 | 675.910071 | 50.0 | 675.910071 | ||
12.0 | 592.533421 | 50.0 | 592.533421 | ||
13.0 | 344.852429 | 50.0 | 344.852429 | ||
14.0 | 323.355891 | 50.0 | 323.355891 | ||
15.0 | 957.863179 | 50.0 | 957.863179 | ||
16.0 | 346.706214 | 50.0 | 346.706214 | ||
17.0 | 90.171422 | 50.0 | 90.171422 | ||
18.0 | 967.958947 | 50.0 | 967.958947 | ||
19.0 | 840.122734 | 50.0 | 840.122734 | ||
20.0 | 343.188731 | 50.0 | 343.188731 | ||
21.0 | 320.030316 | 50.0 | 320.030316 | ||
22.0 | 265.212484 | 50.0 | 265.212484 | ||
23.0 | 418.860600 | 50.0 | 418.860600 |
To summrize low api, you can organize and filter data by network, scenarios, time, node and elements on node.
High API¶
High API is ready to use data. It gives you a business oriented data about adequacy. Today we have: - Get balance to compute net position on a node - Get cost to compute cost on a node - Get Remain Available Capacities
import plotly.graph_objects as go
def plot(y):
return go.Figure(go.Scatter(x=t, y=y.flatten()))
data = agg.get_balance(node='a') # Compute net exchange for all scenario and timestep
plot(data)
data = agg.get_cost(node='b') # Compute cost for all scenario and timestep
plot(data)
data = agg.get_rac() # Compute Remain Available Capacities for all scenarios and timestep
plot(data)